import webapp2
import os
import jinja2
import json

# for logging message to server log
import logging
import datetime


JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True)


# Demonstration how to sanitize input
# Ref: http://jinja.pocoo.org/docs/api/#jinja2.Markup.striptags
class SanitizeHandler(webapp2.RequestHandler):
    def get(self):
        from jinja2 import Markup
        # we assume these are from user

        attack = '<script>alert(\'xss\');</script>'

        # sanitize it with jinja2 striptags, similar function in django also
        sanitized = Markup(attack).striptags()

        template_values = {
            # the object is serialized to a json
            'attack': attack,
            'sanitized': sanitized
        }
        # alternative, you might escape all '<' to  '\u003c' in the server side before sending the json to browser
        template = JINJA_ENVIRONMENT.get_template('templates/sanitization.html')
        self.response.write(template.render(template_values))


class AjaxHandler(webapp2.RequestHandler):
    def get(self):
        # load some json data using ajax
        user_input = {'comment':'Some comment from user', 'attack':'</script><script>alert(\'xss\');</script>'}
        # Always set content-type for json response
        self.response.headers['Content-Type'] = "application/json"
        # data must be serialized by json before sending in response
        self.response.out.write(json.dumps(user_input))

# Render some user input as json and send to templates
class JsonHandler(webapp2.RequestHandler):
    def get(self):

        # the user_input is from the datastore
        user_input = {'comment':'Some comment from user', 'attack':'</script><script>alert(\'xss\');</script>'}

        template_values = {
            # the object is serialized to a json
            'json': json.dumps(user_input)
        }

        # alternative, you might escape all '<' to  '\u003c' in the server side before sending the json to browser
        template = JINJA_ENVIRONMENT.get_template('templates/json.html')
        self.response.write(template.render(template_values))



class CookieHandler(webapp2.RequestHandler):
    def get(self):

        token1 = self.request.cookies.get('token1')
        token2 = self.request.cookies.get('token2')

        template_values = {
            # the object is serialized to a json
            'token1': token1,
            'token2':token2
        }
        template = JINJA_ENVIRONMENT.get_template('templates/cookie.html')
        self.response.write(template.render(template_values))

class CSPHandler(webapp2.RequestHandler):
    def get(self):
        # example on setting CSP programatically
        # self.response.headers['Content-Security-Policy'] = "script-src 'self' ajax.googleapis.com"

        template = JINJA_ENVIRONMENT.get_template('templates/csp.html')
        self.response.write(template.render({}))

# Home page of the demo app
class MainHandler(webapp2.RequestHandler):
    def get(self):

        # write cookie when homepage, expire time is 4 weeks
        expire_date = (datetime.datetime.now()+datetime.timedelta(weeks=4))

        # http://webapp-improved.appspot.com/guide/response.html#guide-response-setting-cookies
        self.response.set_cookie('token1', 'this token cannot be accessed by javascript', expires=expire_date, httponly=True)
        self.response.set_cookie('token2', 'this token can be accessed by javascript', expires=expire_date)

        template = JINJA_ENVIRONMENT.get_template('templates/home.html')
        self.response.write(template.render({}))

app = webapp2.WSGIApplication([
    ('/', MainHandler),
    ('/template/json', JsonHandler),
    ('/ajax/json', AjaxHandler),
    ('/cookie', CookieHandler),
    ('/csp', CSPHandler),
    ('/sanitize', SanitizeHandler)
], debug=True)

